package cqrtplm.adapter.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Strings;
import com.hustcad.plm.basic.constant.ObjectTypeConstant;
import com.hustcad.plm.caddoc.mapper.TyplmCADDocMapper;
import com.hustcad.plm.caddoc.mapper.TyplmCADDocMasterMapper;
import com.hustcad.plm.caddoc.service.impl.TyplmAsynCadDocServiceImpl;
import com.hustcad.plm.caddocapi.service.*;
import com.hustcad.plm.derivedimage.service.TyplmDerivedImageService;
import com.hustcad.plm.derivedimage.vo.DerivedImageVO;
import com.hustcad.plm.lightweight.service.impl.TyplmLightWeightTransferListener;
import com.hustcad.plm.middle.caddoc.service.impl.batchimport.TyplmCadImportDocAndPartUtil;
import com.hustcad.plm.middle.caddocapi.service.TyplmImportCadDocAdapter;
import com.hustcad.plm.pdm.caddoc.model.dto.LightTransferDTO;
import com.hustcad.plm.pdm.caddoc.model.dto.RepresentationDTO;
import com.hustcad.plm.pdm.caddoc.model.query.CadCollectQuery;
import com.hustcad.plm.pdm.caddoc.model.vo.CADWorkspaceVO;
import com.hustcad.plm.pdm.caddoc.model.vo.CadDocVO;
import com.hustcad.plm.pdm.caddoc.model.vo.MDAImportOutDocVo;
import com.hustcad.plm.pdm.common.model.vo.BusinessObjectVO;
import com.hustcad.plm.pdm.common.model.vo.iteration.CommonIteratorVO;
import com.hustcad.plm.pdm.common.util.CommonUtil;
import com.hustcad.plm.pdm.common.util.TyplmPermissionsUtil;
import com.hustcad.plm.pdm.container.model.dto.ContainerTemplateDTO;
import com.hustcad.plm.pdm.container.model.dto.Product;
import com.hustcad.plm.pdm.container.service.ProductService;
import com.hustcad.plm.pdm.container.service.TyplmContainerTemplateService;
import com.hustcad.plm.pdm.doc.dto.SaveDocDTO;
import com.hustcad.plm.pdm.doc.service.TyplmDocQueryService;
import com.hustcad.plm.pdm.doc.service.TyplmDocumentService;
import com.hustcad.plm.pdm.doc.vo.DocDetails;
import com.hustcad.plm.pdm.doc.vo.DocumentVO;
import com.hustcad.plm.pdm.enumeration.service.TyplmLocalePropertyValueService;
import com.hustcad.plm.pdm.file.model.dto.ContentUploadDTO;
import com.hustcad.plm.pdm.file.model.dto.FileDTO;
import com.hustcad.plm.pdm.file.model.dto.FileGroupDTO;
import com.hustcad.plm.pdm.file.model.dto.UploadFileDTO;
import com.hustcad.plm.pdm.file.service.TyplmFileHandleService;
import com.hustcad.plm.pdm.file.util.UploadFileUtils;
import com.hustcad.plm.pdm.filevault.mapper.TyplmContentDataMapper;
import com.hustcad.plm.pdm.filevault.mapper.TyplmObjContentLinkMapper;
import com.hustcad.plm.pdm.filevault.model.dto.UploadDerivedImageDTO;
import com.hustcad.plm.pdm.filevault.model.vo.ContentUploadVO;
import com.hustcad.plm.pdm.filevault.model.vo.FileDataVO;
import com.hustcad.plm.pdm.folder.model.vo.SubfolderVO;
import com.hustcad.plm.pdm.folder.model.vo.SubfolderWebVO;
import com.hustcad.plm.pdm.folder.service.ProductFolderService;
import com.hustcad.plm.pdm.folder.service.TyplmSubFolderLinkService;
import com.hustcad.plm.pdm.iteration.service.TyplmIterationService;
import com.hustcad.plm.pdm.lifestage.service.TyplmLifecycleTemplateService;
import com.hustcad.plm.pdm.mda.dto.CommonParamsDTO;
import com.hustcad.plm.pdm.middle.caddoc.model.dto.Import2dDocForTsDTO;
import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService;
import com.hustcad.plm.pdm.partbom.dto.partimport.PartImportLogVO;
import com.hustcad.plm.pdm.partbom.service.batchimport.TyplmPartBomImportService;
import com.hustcad.plm.pdm.type.service.TyplmTypeService;
import com.hustcad.plm.pdm.user.model.entity.PdmUser;
import com.hustcad.plm.pdm.user.service.TyplmUserService;
import com.hustcad.plm.pdm.user.service.organization.PdmUserService;
import com.hustcad.plm.workspace.service.TyplmWorkspaceService;
import com.ty.basic.constant.*;
import com.ty.basic.entity.cad.CADDocDO;
import com.ty.basic.entity.cad.CADDocMasterDO;
import com.ty.basic.entity.cad.DerivedImageDO;
import com.ty.basic.entity.doc.DocDO;
import com.ty.basic.entity.filevault.ContentDataDO;
import com.ty.basic.entity.filevault.ObjContentLinkDO;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.exception.message.SystemErrorCodeEnum;
import com.ty.basic.handler.exceptionhandler.exception.ResponseCodeEnum;
import com.ty.basic.handler.exceptionhandler.exception.TyException;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import com.ty.basic.util.StringUtil;
import com.ty.queue.dto.QueueSendDTO;
import cqrtplm.adapter.DataTransAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author bj
 * @date 2021/10/19 9:17
 */
@Slf4j
@Repository
@Transactional(rollbackFor = Exception.class)
public class DataTransAdapterImpl implements DataTransAdapter {

    @Resource
    private ProductService productService;
    @Resource
    private TyplmDerivedImageService typlmDerivedImageService;
    @Resource
    private TyplmPdmPartService typlmPdmPartService;
    @Resource
    private TyplmFileHandleService fileHandleService;

    @Resource
    private TyplmTypeService typlmTypeService;

    @Resource
    private TyplmWorkspaceService typlmWorkspaceService;

    @Resource
    private TyplmIterationService typlmIterationService;

    @Resource
    private ProductFolderService productFolderService;

    @Resource
    private TyplmDocQueryService tyDocQueryService;

    @Resource
    private TyplmDocumentService typlmDocumentService;

    @Resource
    private TyplmFileHandleService typlmFileHandleService;

    @Resource
    private UploadFileUtils uploadFileUtils;

    @Lazy
    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;
    @Resource
    private TyplmImportCadDocAdapter importCadDocAdapter;

    @Resource
    private TyplmCadImportDocAndPartUtil typlmCadImportDocAndPartUtil;

    @Resource
    private TyplmCADDocumentService tyCadDocumentService;

    @Resource
    private TyplmSubFolderLinkService typlmSubFolderLinkService;

    @Resource
    private TyplmLifecycleTemplateService tyLifecycleTemplateService;

    @Resource
    private TyplmCADDocMasterMapper tyCadDocMasterMapper;

    @Resource
    private TyplmCADDerivedImageService tyCadDerivedImageService;

    @Resource
    private TyplmMdaCADDocService tyMdaCadDocService;

    @Resource
    private PdmUserService pdmUserService;

    @Resource
    private TyplmUserService tyUserService;

    @Resource
    private TyplmCADDocService tyCadDocService;

    @Resource
    private TyplmPermissionsUtil permissionsUtil;

    @Resource
    private TyplmLocalePropertyValueService tyLocalePropertyValueService;

    @Resource
    private TyplmAsynCadDocService tyAsynCadDocService;

    @Resource
    private TyplmCADDocDealService cadDocDealService;

    @Resource
    private TyplmCADDocMapper typlmCADDocMapper;

    @Resource
    private TyplmContainerTemplateService tyContainerTemplateService;

    @Resource
    private TyplmPartBomImportService typlmPartBomImportService;

    @Value("${url.lightWeightServer}")
    private String lightWeightServer;

    @Value("${spring.kafka.lightweight.normal.topic:}")
    private String lightWeightNormalTopic;

    @Value("${spring.kafka.lightweight.fast.topics:}")
    private String lightWeightFastTopic;

    @Value("${spring.kafka.lightweight.lower.topic:}")
    private String lightWeightLowerTopic;

    @Value("${async.lightweight.transfer.method.url:}")
    private String url;

    @Value("${containerTemplate.name:1}")
    private String containerTemplate;

    @Value("${defaultUserAccount:admin}")
    private String defaultUser;

    private static final String DESCRIPTION = "description";
    private static final Integer DESCRIPTION_MAX_LENGTH = 4000;
    private static final Integer NAME_MAX_LENGTH = 180;
    private static final String ASYN_CAD_TRANSFER = "asynCadTransfer";





    @Override
    public BusinessObjectVO newVersion(String oid, String otype, String subfolderOid) {
        CommonIteratorVO commonIteratorVO = new CommonIteratorVO();
        commonIteratorVO.setId(oid);
        commonIteratorVO.setTypeDefName(otype);
        commonIteratorVO.setSubfolderoid(subfolderOid);
        return typlmIterationService.newVersion(commonIteratorVO);
    }

    @Override
    public DocDO queryLastDocByNumber(String docNumber) {
        return tyDocQueryService.queryLastDocByNumber(docNumber);
    }

    @Override
    public DocumentVO queryDocByOid(BigInteger oid) {
        return typlmDocumentService.queryDocByOid(oid);
    }

    @Override
    public void insertDoc(SaveDocDTO saveDocDto) {
        typlmDocumentService.insertDoc(saveDocDto);
    }

    @Override
    public SubfolderWebVO getSubfolder(String defaultCabinetOid, String defaultCabinetOtype, String folderPath) {

        String parentOid = defaultCabinetOid;
        String parentOtype = defaultCabinetOtype;

        String[] folderNameList = folderPath.split("/");
        SubfolderWebVO result = null;
        for (String folderName : folderNameList) {

            //查询产品库下文件夹，若不存在则新建
            List<SubfolderWebVO> subfolderWebVOS = typlmSubFolderLinkService.querySubfolderByParent(
                    new BigInteger(parentOid), parentOtype);
            List<SubfolderWebVO> resultSubfolderList = null;
            if (ObjectUtils.isNotEmpty(subfolderWebVOS)) {
                resultSubfolderList = subfolderWebVOS.stream().filter(
                        subfolderWebVO -> folderName.equals(subfolderWebVO.getName())).collect(Collectors.toList());
            }
            if (ObjectUtils.isNotEmpty(resultSubfolderList)) {
                result = resultSubfolderList.get(0);
            } else {
                //新建文件夹
                SubfolderVO subfolderVO = new SubfolderVO();
                subfolderVO.setName(folderName);
                subfolderVO.setParentOid(parentOid);
                subfolderVO.setOtype(ObjectTypeConstant.SUBFOLDER_OTYPE);
                subfolderVO.setParentOtype(parentOtype);
                result = productFolderService.createSubfolder(subfolderVO, TyAccountContext.getUser());
            }
            parentOid = result.getOid();
            parentOtype = result.getOtype();

        }
        return result;
    }

    /**
     * 设置产品库信息
     *
     * @param product:
     * @author : bj
     * @date : 2021/10/19 14:09
     * @return: void
     */
    private void newProduct(Product product) {

        List<ContainerTemplateDTO> containerTemplateList = tyContainerTemplateService.queryProductTemplateByName(containerTemplate);
        if (CollectionUtils.isEmpty(containerTemplateList)) {
            //默认产品库模板
            product.setContainerTemplate("产品库容器模板");
            product.setContainerTemplateId("-20202020");
        } else {
            //定制模板
            product.setContainerTemplate(containerTemplateList.get(0).getTemplatename());
            product.setContainerTemplateId(String.valueOf(containerTemplateList.get(0).getMasteredoid()));
        }
        //所有者id
        product.setOwnerOid(TyAccountContext.getUser().getOid().toString());
        //是否私有权限-默认私有
        product.setPrivateAccessContainerInfo("0");
    }

    @Override
    public BusinessObjectVO checkOut(String oid, String otype) {
        CommonIteratorVO commonIteratorVO = new CommonIteratorVO();
        commonIteratorVO.setId(oid);
        commonIteratorVO.setTypeDefName(otype);
        return typlmIterationService.checkOut(commonIteratorVO);
    }

    @Override
    public BusinessObjectVO checkIn(String oid, String otype) {
        return typlmIterationService.checkIn(oid, otype, TyAccountContext.getUser().getOid().toString(), "TC导入");
    }

    @Override
    public void deleteOldFile(BigInteger oid, String otype) {
        // 获取关联的文档附件
        DocDetails docDetails = typlmDocumentService.queryDocDetails(oid, otype);
        List<FileDataVO> primaryFileList = docDetails.getPrimaryFileList();
        List<BigInteger> collect = primaryFileList.stream().map(temp -> CommonUtil.stringToBigIntegers(temp.getFileID())).collect(Collectors.toList());
        typlmFileHandleService.deleteFileByFileIdList(collect);
    }

    @Override
    public List<ContentUploadDTO> uploadDocFile(FileGroupDTO fileGroupDto, String objOtype) {
        return typlmFileHandleService.uploadDocFile(fileGroupDto, objOtype);
    }

    @Override
    public void uploadPartFile(List<MultipartFile> files, PartDO part) {
        try {
            UploadFileDTO uploadFileDto = new UploadFileDTO();
            uploadFileDto.setFiles(files);
            uploadFileDto.setObjOId(part.getOid().toString());
            uploadFileDto.setObjOtype(part.getOtype());
            uploadFileDto.setRoleKey(Constant.FILE_TYPE_SECONDARY);
            uploadFileDto.setContentFlag(false);
            typlmFileHandleService.uploadPartFile(uploadFileDto, MapUtil.empty());
        } catch (Exception e) {
            throw SystemErrorCodeEnum.OBJ_UPLOAD_CANNOT_NEWVERSION.getException("零部件" + part.getOid() + "上传附件失败");
        }
    }

    @Override
    public BigInteger getNextId() {
        return snowflakeIdComponent.getInstance().nextId();
    }

    @Override
    public Map<String, Object> importCadDocAndPart(Document standardXml) {
        String standXml = standardXml.asXML();
        log.info("standXml：{}", standXml);
        Base64.Encoder encoder = Base64.getEncoder();
        String xmlStr = new String(encoder.encode(standXml.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
        Import2dDocForTsDTO paramDTO = new Import2dDocForTsDTO();
        paramDTO.setStandXmlStr(standXml);
        paramDTO.setSourceTs(false);
        return typlmCadImportDocAndPartUtil.createDocAndPart(paramDTO, tyUserService.queryUserByName(defaultUser),
                                                             false);
    }

    @Override
    public void deleteFileByObjOidAndObjType(BigInteger objOid, String objOtype) {
        typlmFileHandleService.deleteFileByObjOidAndObjType(objOid, objOtype);
    }

    @Override
    public List<QueueSendDTO> generateLightWeightFile(Map<String, List<String>> topDocIdMap, Map<String, String> fileOidMap, Map<String, String> cadOidRelFileName) {
        List<RepresentationDTO> representationList = new ArrayList<>();
        for (Map.Entry<String, List<String>> entry : topDocIdMap.entrySet()) {
            String lightWeightType = entry.getKey();
            List<String> topDocIdList = entry.getValue();
            if (CollectionUtils.isEmpty(topDocIdList)) {
                continue;
            }
            for (String docOid : topDocIdList) {
                JSONObject jsonInput = new JSONObject();
                jsonInput.put("docOid", docOid);
                String userOid = this.checkUserExist(TyAccountContext.getUser().getOid().toString());
                jsonInput.put("userOid", userOid);
                jsonInput.put("url", lightWeightServer);
                LightTransferDTO lightTransferDTO = jsonInput.toJavaObject(LightTransferDTO.class);
                RepresentationDTO representationDTO = new RepresentationDTO();
                representationDTO.setIsDefault(lightTransferDTO.getIsDefault());
                representationDTO.setId(lightTransferDTO.getDocOid());
                representationDTO.setDescription(lightTransferDTO.getDescription());
                representationDTO.setName(lightTransferDTO.getName());
                representationDTO.setUserOid(lightTransferDTO.getUserOid());
                representationDTO.setUrl(lightTransferDTO.getUrl());
                representationDTO.setLightweightType(lightWeightType);
                representationList.add(representationDTO);
            }

        }
        return this.createRepresentation(representationList, "", fileOidMap, cadOidRelFileName);
    }
    @Resource
    private TyplmObjContentLinkMapper typlmObjContentLinkMapper;
    @Resource
    private TyplmContentDataMapper typlmContentDataMapper;

    @Override
    public void uploadCadFile(List<MDAImportOutDocVo> cadDocList, Map<String, MultipartFile> docNameRelMultipartFile, Map<String, String> cadIdRelFileName, Map<String, String> fileOidMap) {
        List<ObjContentLinkDO> objContentLinkDOList = new ArrayList<>();
        List<ContentDataDO> contentDataDOList = new ArrayList<>();
        for (MDAImportOutDocVo cadDoc : cadDocList) {
            String docId = cadDoc.getDocId();
            log.info("当前cad文档id为 {}", docId);
            String fileName = cadIdRelFileName.get(docId);
            log.info("当前cad文档名称为 {}", fileName);
            MultipartFile multipartFile1 = docNameRelMultipartFile.get(fileName);
            log.info("当前cad文档对象为 {}", multipartFile1);
            //获取文件流
            MultipartFile multipartFile = docNameRelMultipartFile.get(cadIdRelFileName.get(cadDoc.getDocId()));
            typlmFileHandleService.deleteFileByObjOidAndObjType(new BigInteger(docId), cadDoc.getDocOType());
            FileDTO file = uploadFileUtils.getFile(multipartFile, docId, cadDoc.getDocOType(), Constant.FILE_TYPE_PRIMARY, TyAccountContext.getUser().getOid());
            ContentUploadVO contentUploadVO = typlmFileHandleService.uploadFile(file);
            fileOidMap.put(docId, contentUploadVO.getContentId());
            JSONObject param = new JSONObject();
            param.put("objId", docId);
            param.put("objType", TableTypeConstrant.TY_CADDOC_OTYPE);
            param.put("name", multipartFile.getOriginalFilename());
            param.put("isThumbnail", false);
            param.put("isDefault", false);
            List<DerivedImageVO> presentationList = typlmDerivedImageService.getPresentationList(new BigInteger(docId));
            if (CollUtil.isNotEmpty(presentationList)){
                List<BigInteger> derivedImageOids = presentationList.stream().map(DerivedImageDO::getOid).collect(Collectors.toList());
                typlmDerivedImageService.batchDeletePresentationList(derivedImageOids);
            }
            //表现DO
            DerivedImageDO derivedImageDO = typlmDerivedImageService.webCreateDerivedImage(ListUtil.toList(multipartFile), param.toJSONString());
            Example example = new Example(ObjContentLinkDO.class);
            example.createCriteria().andEqualTo("aoid",derivedImageDO.getCaddocoid())
                            .andEqualTo("aotype",derivedImageDO.getCaddocotype());
            ObjContentLinkDO sourceObjLinkDO = typlmObjContentLinkMapper.selectByExample(example).get(0);
            ObjContentLinkDO objContentLinkDO = new ObjContentLinkDO();
            //表现预览文件link
            BigInteger contentOid = getNextId();
            BeanUtils.copyProperties(sourceObjLinkDO, objContentLinkDO);
            objContentLinkDO.setOid(getNextId());
            objContentLinkDO.setAoid(derivedImageDO.getOid());
            objContentLinkDO.setAotype(derivedImageDO.getOtype());
            objContentLinkDO.setBoid(contentOid);
            objContentLinkDO.setBotype(TableTypeConstrant.TYV_CONTENTDATA_OTYPE);
            objContentLinkDOList.add(objContentLinkDO);
//            typlmObjContentLinkMapper.insert(objContentLinkDO);
            //content正文数据
            Example example2 = new Example(ContentDataDO.class);
            example2.createCriteria().andEqualTo("oid",sourceObjLinkDO.getBoid());
            ContentDataDO sourceContentDO = typlmContentDataMapper.selectByExample(example2).get(0);
            ContentDataDO contentDataDO = new ContentDataDO();
            BeanUtils.copyProperties(sourceContentDO, contentDataDO);
            contentDataDO.setOid(contentOid);
            contentDataDO.setDataformatoid(new BigInteger("235"));
            contentDataDO.setRolekey("INTEVUE");
            contentDataDOList.add(contentDataDO);
//            typlmContentDataMapper.insert(contentDataDO);
        }
        typlmObjContentLinkMapper.batchInsertObjContentLink(objContentLinkDOList);
        typlmContentDataMapper.batchInsertContentDataDO(contentDataDOList);
    }

    @Override
    public boolean verifyCadDocName(String fileName) {
        return importCadDocAdapter.verifyCadDocName(Collections.singletonList(fileName));
    }

    @Override
    public String getWorkSpaceId(Product product, String folderPath) {
        // 根据文件夹路径获取文件夹
        /*SubfolderWebVO subfolder = this.getSubfolder(product.getDefaultCabinetOid(), product.getDefaultCabinetOtype(),
                                                     folderPath);*/

        // 获取个人工作区
        CADWorkspaceVO cadWorkspaceVO = typlmWorkspaceService.queryOrCreateWorkspaceByUser(product.getOid(),
                                                                                           (String) null,
                                                                                           null,
                                                                                           TyAccountContext.getUser()
                                                                                                   .getOid().toString(),
                                                                                           (String) null);
        return cadWorkspaceVO.getWorkSpaceOid();
    }

    @Override
    public String getWorkSpaceIdByDoc(Product product, String folderPath, UserDO userDO) {
        // 获取个人工作区
        CADWorkspaceVO cadWorkspaceVO = typlmWorkspaceService.queryOrCreateWorkspaceByUser(product.getOid(),
                                                                                           (String) null,
                                                                                           null,
                                                                                           userDO.getOid().toString(),
                                                                                           (String) null);
        return cadWorkspaceVO.getWorkSpaceOid();
    }

    @Override
    public String queryLifecycle() {
        return tyLifecycleTemplateService.queryLifecycleByName("Basic").getOid().toString();
    }

    @Override
    public void checkOutCadDocByName(String name, Product product, String workSpaceId) {
        Example example = new Example(CADDocMasterDO.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("cadname", name);
        List<CADDocMasterDO> cadDocMasterList = this.tyCadDocMasterMapper.selectByExample(example);
        if (ObjectUtils.isNotEmpty(cadDocMasterList)) {
            CADDocMasterDO cadDocMasterDO = cadDocMasterList.get(0);
            List<CADDocDO> cadDocDOList = tyCadDocumentService.queryLatestCadDocByMasterOIDs(Collections.singletonList(cadDocMasterDO.getOid()), TyAccountContext.getUser().getOid().toString());
            if (ObjectUtils.isNotEmpty(cadDocDOList)) {
                tyCadDocumentService.checkoutCadDoc(cadDocDOList.get(0), TyAccountContext.getUser().getOid(), workSpaceId);
            }
        }
    }

    @Override
    public String getTypeOidByName(String name) {
        return typlmTypeService.getTypeOidByName(name).toString();
    }

    private String checkUserExist(String userId) {
        try {
            if (Objects.isNull(userId)) {
                userId = String.valueOf(TyAccountContext.getUser().getOid());
            } else {
                BigInteger bigUserOid = new BigInteger(userId);
                PdmUser pdmUser = this.pdmUserService.getUserByOid(bigUserOid);
                UserDO userDO = this.tyUserService.selectByOid(bigUserOid);
                if (Objects.isNull(pdmUser) && Objects.isNull(userDO)) {
                    throw SystemErrorCodeEnum.USER_NOT_EXISTS.getException("用户信息为空！");
                }
            }

            return userId;
        } catch (Exception var5) {
            throw SystemErrorCodeEnum.USER_NOT_EXISTS.getException("用户信息为空！");
        }
    }

    private List<QueueSendDTO> createRepresentation(List<RepresentationDTO> representationDTOS, String priority, Map<String, String> fileOidMap, Map<String, String> cadOidRelFileName) {
        UserDO user = getUserByRepresentationDTO(representationDTOS);
        List<RepresentationDTO> distinctList = new ArrayList<>();
        paramCheck(representationDTOS, user, distinctList);
        String processPriority = getPriority(priority);
        if (log.isDebugEnabled()) {
            log.debug("priority:{}", processPriority);
        }
        String tsUrl = getTsUrl(representationDTOS);
        List<QueueSendDTO> sendDTOList = new ArrayList<>();
        List<String> roleKeyEnumList = new ArrayList<>(tyLocalePropertyValueService.queryLocaleValueByItem(
                new ArrayList<>(), RoleKeyConstant.ROLE_KEY_ENUM, TyAccountContext.getLanguage()).keySet());

        for (RepresentationDTO representationDTO : distinctList) {
            LightTransferDTO lightTransferDTO = null;
            if (null!=user) {
             lightTransferDTO = getLightTransferDTO(representationDTO, user.getOid(), tsUrl);
            }
            if (null!=lightTransferDTO) {
            CadCollectQuery cadCollectQuery = new CadCollectQuery();
            BigInteger cadDocId = new BigInteger(lightTransferDTO.getDocOid());
            cadCollectQuery.setOid(Collections.singletonList(cadDocId));
            cadCollectQuery.setCollectType("ALL");
            cadCollectQuery.setPageNum(1);
            cadCollectQuery.setPageSize(100000);
            cadCollectQuery.setCollectPolicy("Latest");
            cadCollectQuery.setSubCollectType("ALL");
            PageInfo<CadDocVO> result = tyMdaCadDocService.collectRefDocMda(cadCollectQuery, new BigInteger(lightTransferDTO.getUserOid()));
            List<String> childFileOidList = result.getList().stream().map(CadDocVO::getFileOID).collect(Collectors.toList());
            lightTransferDTO.setChildFileOid(childFileOidList);
            // 获取子零件cadDocOids
            Set<Map.Entry<String, String>> entries = fileOidMap.entrySet();
            List<Map.Entry<String, String>> collect = entries.stream().filter(entry -> childFileOidList.contains(entry.getValue())).collect(Collectors.toList());
            List<String> childCadDocOids = collect.stream().map(Map.Entry::getKey).collect(Collectors.toList());
            lightTransferDTO.setChildDocOid(childCadDocOids);


            String fileOid = fileOidMap.get(representationDTO.getId());
            String fileName = cadOidRelFileName.get(representationDTO.getId());
            lightTransferDTO.setFileName(fileName);
            lightTransferDTO.setIsForceCreated("Y");
            if (StringUtils.isNotEmpty(fileOid)) {
                lightTransferDTO.setFileOid(fileOid);
            } else {
                log.info("Can not find cadDoc File:{}", representationDTO.getId());
            }
            Set<String> roleKeySet = verifyRoleKeyType(representationDTO.getLightweightType(),
                    roleKeyEnumList, fileName);
            lightTransferDTO.setRoleKeySet(roleKeySet);
            QueueSendDTO sendDTO = lightWeightTransfer(lightTransferDTO, processPriority);
            sendDTO.setLightweightType(roleKeySet);
            sendDTOList.add(sendDTO);
            }
        }
        return sendDTOList;
    }

    @Override
    public void uploadDwgLightFile(Map<String, String> cadOidRelFileName,
                                   Map<String, MultipartFile> docNameRelPdfFile) {
        String userId = String.valueOf(TyAccountContext.getUser().getOid());

        for (Map.Entry<String, String> cadRelFileEntry : cadOidRelFileName.entrySet()) {
            if (!docNameRelPdfFile.containsKey(cadRelFileEntry.getValue())) {
                continue;
            }

            UploadDerivedImageDTO input = new UploadDerivedImageDTO();
            input.setCadDocOid(cadRelFileEntry.getKey());
            input.setDerivationType("pdf");
            input.setIsDefault("Y");
            input.setDerivedName("default");
            input.setDescription("");

            CommonParamsDTO infoJson = new CommonParamsDTO();
            infoJson.setClientID("111");
            infoJson.setOrderID("111");
            infoJson.setUserID(userId);
            infoJson.setInput(JSONObject.parseObject(JSONObject.toJSONString(input)));

            cadDocDealService.uploadLightFile(docNameRelPdfFile.get(cadRelFileEntry.getValue()),
                                              JSONObject.toJSONString(infoJson));
        }

    }

    /**
     * 导入零部件及零部件结构
     *
     * @param standXml 标准导入XML
     * @return 日志信息
     */
    @Override
    public Map<String, List<PartImportLogVO>> importPartAndBom(Document standXml) {

        String xml = standXml.asXML();
        Import2dDocForTsDTO paramDTO = new Import2dDocForTsDTO();
        paramDTO.setStandXmlStr(xml);
        paramDTO.setSourceTs(false);
        return typlmPartBomImportService.batchImportPartBom(xml, CommonUtil.getUser().getOid());
    }

    @Override
    public CADDocDO getLastCadDocByNumber(String number) {
        Example example = new Example(CADDocMasterDO.class);
        example.createCriteria().andEqualTo("docnumber",number);
        List<CADDocMasterDO> cadDocMasterDOS = tyCadDocMasterMapper.selectByExample(example);
        if (!cadDocMasterDOS.isEmpty()) {
            BigInteger masteredOid = cadDocMasterDOS.get(0).getOid();
            Example cadDocExample = new Example(CADDocDO.class);
            cadDocExample.createCriteria().andEqualTo("masteredoid", masteredOid).andEqualTo("islastiterated", "1");
            cadDocExample.orderBy("versionsort").desc().orderBy("iterationid").desc();
            List<CADDocDO> cadDocDOS = typlmCADDocMapper.selectByExample(cadDocExample);
            if (!cadDocDOS.isEmpty()) {
                //最新
                return cadDocDOS.get(0);
            }
        }
        return null;
    }

    private Set<String> verifyRoleKeyType(String roleKey, List<String> roleKeyEnumList, String fileName) {
        // 如果lightweightType为null,默认查ALL
        if (Objects.isNull(roleKey)) {
            return getAllRoleKeyByFileName(fileName, roleKeyEnumList);
        }
        String[] roleKeyArray = roleKey.split(",");
        Set<String> legalRoleKeySet = new HashSet<>();
        Set<String> illegalRoleKeySet = new HashSet<>();
        if (Arrays.stream(roleKeyArray).anyMatch(RoleKeyConstant.ALL::equalsIgnoreCase)) {
            return getAllRoleKeyByFileName(fileName, roleKeyEnumList);
        }
        for (String key : roleKeyArray) {
            // 忽略空白字符串,满足场景,若lightweightType为"",默认查ALL
            if (StringUtils.isBlank(key)||roleKeyEnumList.stream().noneMatch(key::equalsIgnoreCase)) {
                continue;
            }

            for (String roleKeyEnum : roleKeyEnumList) {
                if (key.equalsIgnoreCase(roleKeyEnum)) {
                    legalRoleKeySet.add(roleKeyEnum);
                    break;
                }
            }
        }
        if (CollectionUtils.isEmpty(legalRoleKeySet)) {
            if (!CollectionUtils.isEmpty(illegalRoleKeySet)) {
                TyException.throwSingleTyExceptionVarargs(
                        ResponseCodeEnum.BIZ_CAD_LIGHTWEIGHT_CONVERSION_TYPE_NOT_SUPPORTED,
                        String.join(",", illegalRoleKeySet));
            }
            return getAllRoleKeyByFileName(fileName, roleKeyEnumList);
        }
        // 校验最终结果roleKeySet是否和文件类型匹配
        return verifyFileNameExtension(legalRoleKeySet, fileName, roleKeyEnumList);
    }

    private Set<String> getAllRoleKeyByFileName(String fileName, List<String> roleKeyEnumList) {
        // 根据文件名查询ALL对应的RoleKeySet,先根据文件名查询所有可转换类型
        List<String> allRoleKeyList = tyAsynCadDocService.getRoleKeyByFileName(fileName);
        if (CollectionUtils.isEmpty(allRoleKeyList)) {
            TyException.throwSingleTyExceptionVarargs(
                    ResponseCodeEnum.BIZ_CAD_NOT_CONFIGURED_LIGHTWEIGHT_FORMAT);
        }
        Set<String> allRoleKeySet = new HashSet<>();
        // 讲配置文件中对应类型的所有roleKey映射成对应的枚举项
        for (String roleKey : allRoleKeyList) {
            for (String enumItem : roleKeyEnumList) {
                if (enumItem.equalsIgnoreCase(roleKey)) {
                    allRoleKeySet.add(enumItem);
                }
            }
        }
        return allRoleKeySet;
    }

    private Set<String> verifyFileNameExtension(Set<String> legalRoleKeySet, String fileName,
                                                List<String> roleKeyEnumList) {
        Set<String> allRoleKeySet = getAllRoleKeyByFileName(fileName, roleKeyEnumList);
        // 先判断legalRoleKeySet是否存在ALL,为ALL需要转换
        if (legalRoleKeySet.stream().anyMatch(RoleKeyConstant.ALL::equalsIgnoreCase)) {
            return allRoleKeySet;
        }
        List<String> roleKeyList = new ArrayList<>(legalRoleKeySet);
        List<String> illegalRoleKeyType = roleKeyList.stream()
                .filter(item -> allRoleKeySet.stream().noneMatch(item::equalsIgnoreCase)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(illegalRoleKeyType)) {
            TyException.throwSingleTyExceptionVarargs(
                    ResponseCodeEnum.BIZ_CAD_TYPE_NOT_MATCH_SPECIFIED_LIGHTWEIGHT_FORMAT);
        }
        return legalRoleKeySet;
    }

    private QueueSendDTO lightWeightTransfer(LightTransferDTO lightTransferDTO, String processPriority) {
        JSONObject obj = new JSONObject();
        obj.put(AsyncConstant.CLASSPATH, TyplmAsynCadDocServiceImpl.class.getName());
        obj.put(AsyncConstant.ADAPTERLISTENTERPATH, TyplmLightWeightTransferListener.class.getName());
        obj.put(AsyncConstant.METHOD, ASYN_CAD_TRANSFER);
        obj.put(AsyncConstant.TASKID, System.currentTimeMillis());
        JSONArray arr = new JSONArray();
        JSONObject param = new JSONObject();
        param.put(AsyncConstant.KEY, LightTransferDTO.class);
        param.put(AsyncConstant.VALUE, lightTransferDTO);
        arr.add(param);
        obj.put(AsyncConstant.PARAMS, arr);
        QueueSendDTO sendDTO = new QueueSendDTO();
        sendDTO.setDefaultPerformance(lightTransferDTO.getIsDefault())
                .setObjId(new BigInteger(lightTransferDTO.getDocOid()))
                .setReqJson(obj).setJobId(UUID.randomUUID().toString());
        if (PriorityConstant.HIGH.equalsIgnoreCase(processPriority)) {
            sendDTO.setTopic(lightWeightFastTopic);
        } else if (PriorityConstant.LOW.equalsIgnoreCase(processPriority)) {
            sendDTO.setTopic(lightWeightLowerTopic);
        } else {
            sendDTO.setTopic(lightWeightNormalTopic);
        }
        return sendDTO;
    }

    private LightTransferDTO getLightTransferDTO(RepresentationDTO representationDTO, BigInteger userOid,
                                                 String tsUrl) {
        LightTransferDTO lightTransferDTO = new LightTransferDTO();
        lightTransferDTO.setUserOid(userOid + "");
        lightTransferDTO.setDocOid(representationDTO.getId());
        if (StringUtils.isNotEmpty(tsUrl)) {
            lightTransferDTO.setUrl(tsUrl);
        } else {
            lightTransferDTO.setUrl(url);
        }
        lightTransferDTO.setName(representationDTO.getName());
        lightTransferDTO.setDescription(representationDTO.getDescription());
        lightTransferDTO.setIsDefault(representationDTO.getIsDefault());
        lightTransferDTO.setIsTransferChild(representationDTO.getIsTransferChild());
        return lightTransferDTO;
    }

    private String getTsUrl(List<RepresentationDTO> representationDTOS) {
        String result = "";
        if (!CollectionUtils.isEmpty(representationDTOS) && representationDTOS.get(0) != null) {
            result = representationDTOS.get(0).getUrl();
        }
        return result;
    }

    private String getPriority(String priority) {
        String result = null;
        if (StringUtils.isEmpty(priority) || PriorityConstant.MIDDLE.equalsIgnoreCase(priority)) {
            result = PriorityConstant.MIDDLE;
        } else if (PriorityConstant.HIGH.equalsIgnoreCase(priority)) {
            result = PriorityConstant.HIGH;
        } else if (PriorityConstant.LOW.equalsIgnoreCase(priority)) {
            result = PriorityConstant.LOW;
        } else {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.ACC_PARAMETER_ENUM_ERROR,
                    PriorityConstant.HIGH + "," + PriorityConstant.MIDDLE + "," + PriorityConstant.LOW);
        }
        return result;
    }

    private void oidAndNameCheck(RepresentationDTO representationDTO, Set<String> illegalIdlList, List<BigInteger> cadOidList) {
        if (StringUtils.isEmpty(representationDTO.getId())) {
            illegalIdlList.add(representationDTO.getId());
        }

        try {
            BigInteger oid = new BigInteger(representationDTO.getId());
            cadOidList.add(oid);
        } catch (NumberFormatException var5) {
            illegalIdlList.add(representationDTO.getId());
        }

        if (StringUtils.isEmpty(representationDTO.getName())) {
            representationDTO.setName("default");
        }

        if (!representationDTO.getName().matches("\\s*|[^/\\\\:*?<>|\"]+")) {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.CALL_PARAMETER_ILLEGAL, representationDTO.getName());
        }

        if (representationDTO.getName().length() > NAME_MAX_LENGTH) {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.ACC_PARAMETER_EXCEED_LENGTH, "name", NAME_MAX_LENGTH + "");
        }

    }

    private List<BigInteger> paramCheck(List<RepresentationDTO> representationDTOList, UserDO userDO, List<RepresentationDTO> distinctList) {
        List<BigInteger> cadOidList = new ArrayList<>();
        if (CollectionUtils.isEmpty(representationDTOList)) {
            return cadOidList;
        }
        Set<String> illegalIdlList = new HashSet<>();
        for (RepresentationDTO representationDTO : representationDTOList) {
            // 校验name和oid
            oidAndNameCheck(representationDTO, illegalIdlList, cadOidList);
            // description为null设置为默认空字符串
            if (StringUtils.isEmpty(representationDTO.getDescription())) {
                representationDTO.setDescription("");
            }
            // description最大长度4000
            if (representationDTO.getDescription().length() > DESCRIPTION_MAX_LENGTH) {
                TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.ACC_PARAMETER_EXCEED_LENGTH, DESCRIPTION,
                        DESCRIPTION_MAX_LENGTH + "");
            }
            // isDefault不为Y就为默认N
            if (!StringUtils.isEmpty(representationDTO.getIsDefault()) && RoleKeyConstant.DEFAULT.equalsIgnoreCase(
                    representationDTO.getIsDefault())) {
                representationDTO.setIsDefault(RoleKeyConstant.DEFAULT);
            } else {
                representationDTO.setIsDefault(RoleKeyConstant.NOT_DEFAULT);
            }
        }
        if (!CollectionUtils.isEmpty(illegalIdlList)) {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.CALL_PARAMETER_ILLEGAL,
                    String.join(",", illegalIdlList));
        }
        // 去重
        distinctList.addAll(distinctRepresent(representationDTOList, cadOidList));
        List<CADDocDO> cadDocDOList = tyCadDocService.queryCADDocByOIDs(cadOidList);
        judgeCadDocExist(cadDocDOList, cadOidList, userDO);
        permissionsUtil.checkObjectPermissionList(userDO, new ArrayList<>(cadDocDOList), AuthorityConstant.READ);
        return cadOidList;
    }

    private void judgeCadDocExist(List<CADDocDO> cadDocDOList, List<BigInteger> cadDocOidList, UserDO user) {
        List<BigInteger> queryCadDocOidList = cadDocDOList.stream().map(CADDocDO::getOid).collect(Collectors.toList());
        String result = cadDocOidList.stream()
                .filter(id -> !queryCadDocOidList.contains(id))
                .distinct()
                .map(BigInteger::toString)
                .collect(Collectors.joining(","));
        if (!Strings.isNullOrEmpty(result)) {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.BIZ_OBJECT_NOT_FOUND, result);
        }
        for (CADDocDO cadDocDO : cadDocDOList) {
            if (PartConstant.WRK.equalsIgnoreCase(cadDocDO.getLockstateinfo()) && !cadDocDO.getUpdatoroid()
                    .equals(user.getOid())) {
                UserDO locker = tyUserService.queryUserByKey(cadDocDO.getUpdatoroid());
                TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.BIZ_OBJECT_HAVE_CHECKED_OUT,
                        CommonUtil.getEntityDisplayName(cadDocDO), CommonUtil.getEntityDisplayName(locker));
            }
        }
    }

    private List<RepresentationDTO> distinctRepresent(List<RepresentationDTO> representationDTOList,
                                                      List<BigInteger> cadOidList) {
        Map<String, List<RepresentationDTO>> cadIdMap = representationDTOList.stream()
                .collect(Collectors.groupingBy(RepresentationDTO::getId));
        List<DerivedImageDO> derivedImageDOList = tyCadDerivedImageService.queryDerivedImageByCADDocs(cadOidList);
        Map<BigInteger, List<DerivedImageDO>> derivedImageMap = derivedImageDOList.stream()
                .collect(Collectors.groupingBy(DerivedImageDO::getCaddocoid));
        List<DerivedImageDO> defaultDerivedImageList = derivedImageDOList.stream()
                .filter(derivedImageDO -> derivedImageDO.getDefaultrepresentation() != null
                        && derivedImageDO.getDefaultrepresentation() == 1L)
                .collect(Collectors.toList());
        List<RepresentationDTO> result = new ArrayList<>();
        for (Map.Entry<String, List<RepresentationDTO>> entry : cadIdMap.entrySet()) {
            List<RepresentationDTO> value = entry.getValue();
            // 用于for循环校验改caddoc的默认表现被设置为非默认，但是又不给定默认的情况
            List<RepresentationDTO> judgeDefaultExistList = new ArrayList<>();
            if (value.size() <= 1) {
                // 此场景为新建
                if (derivedImageMap.get(new BigInteger(entry.getKey())) == null && value.get(0) != null) {
                    value.get(0).setIsDefault(RoleKeyConstant.DEFAULT);
                }
                judgeDefaultExistList.addAll(value);
                setDefault(judgeDefaultExistList, defaultDerivedImageList, entry.getKey());
                result.addAll(judgeDefaultExistList);
                continue;
            }
            // 用于去除name重复的list
            List<String> nameList = new ArrayList<>();
            // 用于筛选name不同且第一个为Y的,用于name不同但却有多个Y的情况,第一个为Y,其余改为N
            List<String> firstDefaultNameList = new ArrayList<>();
            for (RepresentationDTO representationDTO : value) {
                if (!nameList.contains(representationDTO.getName())) {
                    nameList.add(representationDTO.getName());
                    if (RoleKeyConstant.DEFAULT.equalsIgnoreCase(representationDTO.getIsDefault())
                            && firstDefaultNameList.isEmpty()) {
                        firstDefaultNameList.add(representationDTO.getName());
                    } else {
                        representationDTO.setIsDefault(RoleKeyConstant.NOT_DEFAULT);
                    }
                    judgeDefaultExistList.add(representationDTO);
                }
            }
            // 此场景为都是新建，传入多个相同caddocId但是不同name,都没有默认Y的,就默认取第一个
            if (derivedImageMap.get(new BigInteger(entry.getKey())) == null && CollectionUtils.isEmpty(
                    firstDefaultNameList)) {
                value.get(0).setIsDefault(RoleKeyConstant.DEFAULT);
            }
            setDefault(judgeDefaultExistList, defaultDerivedImageList, entry.getKey());
            result.addAll(judgeDefaultExistList);
        }
        return result;
    }

    private void setDefault(List<RepresentationDTO> judgeDefaultExistList,
                            List<DerivedImageDO> defaultDerivedImageDOList, String cadId) {
        List<String> defaultImageName = judgeDefaultExistList.stream()
                .filter(representationDTO -> RoleKeyConstant.DEFAULT.equalsIgnoreCase(representationDTO.getIsDefault()))
                .map(RepresentationDTO::getName)
                .collect(Collectors.toList());
        // 默认表现只能唯一
        List<DerivedImageDO> cadIdMatchDerivedImageList = defaultDerivedImageDOList.stream()
                .filter(derivedImageDO -> derivedImageDO.getCaddocoid().equals(new BigInteger(cadId)))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(defaultDerivedImageDOList) && CollectionUtils.isEmpty(defaultImageName)
                && !CollectionUtils.isEmpty(cadIdMatchDerivedImageList) && cadIdMatchDerivedImageList.get(0) != null) {
            DerivedImageDO defaultDerivedImageDO = cadIdMatchDerivedImageList.get(0);
            for (RepresentationDTO representationDTO : judgeDefaultExistList) {
                if (representationDTO.getName().equals(defaultDerivedImageDO.getName())) {
                    representationDTO.setIsDefault(RoleKeyConstant.DEFAULT);
                }
            }
        }
    }

    private UserDO getUserByRepresentationDTO(List<RepresentationDTO> representationDTOS) {
        UserDO userDO;
        List<String> userOidList = representationDTOS.stream().map(RepresentationDTO::getUserOid).filter(StringUtil::isNotEmpty).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(userOidList) && userOidList.get(0) != null) {
            userDO = this.tyUserService.queryUserByKey(CommonUtil.stringToBigIntegers(userOidList.get(0)));
            if (userDO == null) {
                TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.BIZ_USER_NOT_FOUND, userOidList.get(0));
            }
        } else {
            userDO = TyAccountContext.getUser();
        }

        return userDO;
    }
}
